﻿using System;
using System.ComponentModel;
using System.Text;
using System.Web.UI;

namespace MyLib.Web.UI {
	/// <summary>
	/// 
	/// </summary>
	[DefaultProperty("Digit")]
	[ToolboxData("<{0}:MyNumericValidator runat=\"server\"></{0}:MyNumericValidator>")]
	public sealed class MyNumericValidator : MyFormatBaseValidator {
		/// <summary>
		/// 
		/// </summary>
		private const bool DefaultAllowNegative = false;

		/// <summary>
		/// 
		/// </summary>
		private const int DefaultDigit = 9;

		/// <summary>
		/// 
		/// </summary>
		private const int DefaultDecimalDigit = 2;

		/// <summary>
		/// 
		/// </summary>
		private const string ExpFmt1 =
@"\d{{1,{0}}}";

		/// <summary>
		/// 
		/// </summary>
		private const string ExpFmt2 =
@"\.\d{{1,{1}}}|\d{{1,{0}}}(\.\d{{1,{1}}})?";

		/// <summary>
		/// 
		/// </summary>
		[Category("Action")]
		[Bindable(false)]
		[Browsable(true)]
		[DefaultValue(DefaultAllowNegative)]
		public bool AllowNegative {
			get {
				var v = ViewState["AllowNegative"];
				if (v == null) {
					return DefaultAllowNegative;
				} else {
					return (bool)v;
				}
			}
			set {
				ViewState["AllowNegative"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Category("Appearance")]
		[Bindable(false)]
		[Browsable(true)]
		[DefaultValue(DefaultDigit)]
		public int Digit {
			get {
				var v = ViewState["Digit"];
				if (v == null) {
					return DefaultDigit;
				} else {
					return (int)v;
				}
			}
			set {
				if (value < 1) {
					throw new ArgumentOutOfRangeException("Value of Digit cannot less than 1, bus was " + value);
				}

				ViewState["Digit"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Category("Appearance")]
		[Bindable(false)]
		[Browsable(true)]
		[DefaultValue(DefaultDecimalDigit)]
		public int DecimalDigit {
			get {
				var v = ViewState["DecimalDigit"];
				if (v == null) {
					return DefaultDecimalDigit;
				} else {
					return (int)v;
				}
			}
			set {
				if (value < 0) {
					throw new ArgumentOutOfRangeException("Value of DecimalDigit cannot less than 0, bus was " + value);
				}

				ViewState["DecimalDigit"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected override string GetExpression() {
			var exp = new StringBuilder();

			// Sign char.
			if (AllowNegative) {
				exp.Append(@"(\+|\-)?");
			} else {
				exp.Append(@"(\+)?");
			}

			exp.Append("(");
			if (DecimalDigit > 0) {
				exp.AppendFormat(ExpFmt2, Digit, DecimalDigit);
			} else {
				exp.AppendFormat(ExpFmt1, Digit);
			}
			exp.Append(")");

			return exp.ToString();
		}
	} // end of MyNumericValidator.
}
